﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Kinect;
using Forms = System.Windows.Forms;
using System.Windows;
using System.Runtime.InteropServices;
using WindowsInput;
using System.Diagnostics;
using VKeyboard;
namespace Gestures
{
    public class GestureControl
    {
        [DllImport("user32.dll")]
        static extern IntPtr GetForegroundWindow();

        [DllImport("user32.dll")]
        private static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
        private const int SC_CLOSE = 0xF060;
        private const int SW_SHOWMINIMIZED = 2;
        private const int SW_SHOWMAXIMIZED = 3;
        private const int SW_SHOWNORMAL = 1;
        public static int isKeyboardUp = 0;
        private HandWatcher rightHandWatcher;
        private HandWatcher leftHandWatcher;
        private HandWatcher rightHandWatcherExpand;
        private HandWatcher leftHandWatcherExpand;
        private HandWatcher rightHandWatcherLeft;
        private HandWatcher rightHandWatcherIn;
        private HandWatcher leftHandWatcherIn;
        public static int windowKeyPressed = 0;
        private int tabPress = 0;
        private bool startTimer = false;
        private int timer = 0;
        public static KeyboardHolder vk = new KeyboardHolder();


        public GestureControl()
        {
            rightHandWatcher = new HandWatcher("{RIGHT}", 80, 200, "down");
            leftHandWatcher = new HandWatcher("{LEFT}", 80,200, "down");
            rightHandWatcherExpand = new HandWatcher("{RIGHT}", 200, 80, "up");
            leftHandWatcherExpand = new HandWatcher("{LEFT}", 80, 200, "up");
            rightHandWatcherLeft = new HandWatcher("{RIGHT}", 280, 260, "left");
            rightHandWatcherIn = new HandWatcher("{RIGHT}", 80, 200, "in");
            leftHandWatcherIn = new HandWatcher("{RIGHT}", 200, 80, "in");
            
        }

        public void DetermineAction(Point leftHandPoint, Point rightHandPoint, Joint rightHand, Joint leftHand)
        {
               checkWindowsAltKey(leftHandPoint);

               rightHandWatcherIn.pinchToZoom(leftHandPoint, rightHandPoint);
               leftHandWatcherIn.pinchToZoom(leftHandPoint, rightHandPoint);
               rightHandWatcher.DetermineTwoHandAction(rightHandPoint, leftHandPoint);
               leftHandWatcher.DetermineTwoHandAction(rightHandPoint, leftHandPoint);
               rightHandWatcherLeft.DetermineHandAction(rightHandPoint);
              vk.setLeftHandPosition(leftHandPoint, leftHand);
              vk.setRightHandPosition(rightHandPoint, rightHand);
              vk.Show();
        }

        public void checkWindowsAltKey(Point leftHandPoint)
        {
            if (startTimer)
            {
                timer++;
            }

            if (leftHandPoint.Y < 60)
            {
                if (!startTimer)
                {
                    timer = 0;
                    startTimer = true;

                }
            }
            else
            {
                startTimer = false;
            }

            if (leftHandPoint.Y < 60 && timer > 75)
            {
                
                if (tabPress == 0)
                {
                    InputSimulator.SimulateKeyDown(WindowsInput.VirtualKeyCode.LWIN);
                    InputSimulator.SimulateKeyPress(WindowsInput.VirtualKeyCode.TAB);
                    tabPress = 1;
                    windowKeyPressed = 1;
                   
                }
         
            }
            else
            {
                InputSimulator.SimulateKeyUp(WindowsInput.VirtualKeyCode.LWIN);
                tabPress = 0;
                windowKeyPressed = 0;
                //startTimer = false;
                
            }
          
        }

  
        private class HandWatcher
        {
            private bool startTimer = false;
            private int timer = 0;
            int tabpressHW = 0;
            private string keyboardAction;
            private string swipeDirection;
            private int startingThreshold;
            private int endingThreshold;
            public IntPtr hWnd = GetForegroundWindow();
           
           
            public HandWatcher(string keyboardAction, int startingThreshold, int endingThreshold, string swipeDirection)
            {
                this.keyboardAction = keyboardAction;
                this.startingThreshold = startingThreshold;
                this.endingThreshold = endingThreshold;
                this.swipeDirection = swipeDirection;
            }

            public void pinchToZoom(Point lhandPoint, Point rhandPoint)
            {
               
                 if (startTimer)
                {
                    timer++;
                }


                 if (lhandPoint.X < 160 && lhandPoint.Y < 95 && rhandPoint.X > 190 && rhandPoint.Y >= 160)
                {
                    if (!startTimer)
                    {
                        startTimer = true;
                        
                    }
                 
                }

                if (lhandPoint.Y > 100 && lhandPoint.X > 175 && rhandPoint.X < 300 && rhandPoint.Y < 150 && startTimer && timer < 75 )
                    
                {
                    hWnd = GetForegroundWindow();
                    if (!hWnd.Equals(IntPtr.Zero))
                    {

                      ShowWindowAsync(hWnd, SW_SHOWMINIMIZED);
                    }
                    startTimer = false;
                    timer = 0;
             
                }

                if (lhandPoint.Y > 100 && lhandPoint.X > 175 && rhandPoint.X < 300 && rhandPoint.Y < 150)
                {
                    if (!startTimer)
                    {
                        startTimer = true;

                    }
                }

                if (  lhandPoint.X < 160 && lhandPoint.Y < 95 && rhandPoint.X > 190 && rhandPoint.Y > 160 && startTimer && timer <75 )
                {
                    if (!hWnd.Equals(IntPtr.Zero))
                    {
                        ShowWindowAsync(hWnd, SW_SHOWMAXIMIZED);
                        timer = 0;
                        startTimer = false;
                    }

                   
                }

                if (timer >= 75)
                {
                    startTimer = false;
                    timer = 0;
                    
                }
               
            }

            public void DetermineTwoHandAction(Point lhandPoint, Point rhandPoint)
            {
                 
                if (startTimer)
                {
                    timer++;
                }

                if (rhandPoint.X > 200 && rhandPoint.X < 250 && lhandPoint.X > 200 && lhandPoint.X < 250 && lhandPoint.Y > 180 && rhandPoint.Y > 180)
                {
                    if (!startTimer)
                    {
                        startTimer = true;

                    }
                    
                }

                if (lhandPoint.X > 325 && rhandPoint.X < 125 && lhandPoint.Y > 180 && rhandPoint.Y > 180 && timer < 35) 
                {
                   
                        if (isKeyboardUp == 0)
                        {
                            System.Threading.Thread.Sleep(500);
                            isKeyboardUp = 1;
                            vk.Show();
                            //Process.Start(@"C:\Kinect Interface\cis457-kinect-interface\GestureControl\VKeyboard.exe");
                            // ShowWindowAsync(hWnd, SW_SHOWMINIMIZED);
                        }
                   
                    startTimer = false;
                    timer = 0;

                }

                if (determineUpperThreshold(lhandPoint) && determineUpperThreshold(rhandPoint))
                {
                    if (!startTimer)
                    {
                        startTimer = true;
                    }
                }

                if (determineLowerThreshold(rhandPoint) && determineLowerThreshold(lhandPoint) && startTimer && timer < 50)
                {

                    if (swipeDirection == "down")
                    {

                        if (!hWnd.Equals(IntPtr.Zero))
                        {
                           //ShowWindowAsync(hWnd, SW_SHOWMINIMIZED);
                        }
                        startTimer = false;
                        timer = 0;
                    }

                }


                
            }
            public void DetermineHandAction(Point handPoint)
            {
                if (startTimer)
                {
                    timer++;
                }

                if (determineUpperThreshold(handPoint))
                {
                    if (!startTimer)    
                    {
                        startTimer = true;
                    }
                }

                if (determineLowerThreshold(handPoint) && startTimer && timer < 40 )
                {
                    
                   if (swipeDirection == "left")
                    {   
                       if (windowKeyPressed == 1 && tabpressHW == 0)
                        {
                            InputSimulator.SimulateKeyPress(WindowsInput.VirtualKeyCode.TAB);
                            tabpressHW = 1;
                            timer = 0;
                        }
                      
                       

                    }
                }
                if (timer >= 40)
                {
                    startTimer = false;
                    timer = 0;
                    tabpressHW = 0;

                }

               
            }

            private bool determineUpperThreshold(Point handPoint)
            {
                if (swipeDirection == "down")
                    return handPoint.Y < startingThreshold;
                else if (swipeDirection == "up")
                    return handPoint.Y >= endingThreshold;
                else if (swipeDirection == "left")
                    return handPoint.X > startingThreshold;
                else
                    return handPoint.X > startingThreshold;
            }

            private bool determineLowerThreshold(Point handPoint)
            {
                if (swipeDirection == "down")
                    return handPoint.Y > endingThreshold;
                else if (swipeDirection == "up")
                    return handPoint.Y <= endingThreshold;
                else if (swipeDirection == "left")
                    return handPoint.X < endingThreshold;
                else
                    return handPoint.X > startingThreshold;
            }
        }
    }
}
